package nsu.edu.zsq.service.impl.sys;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import lombok.extern.slf4j.Slf4j;
import nsu.edu.zsq.bean.Student;
import nsu.edu.zsq.bean.StudentExample;
import nsu.edu.zsq.bean.StudentExample.Criteria;
import nsu.edu.zsq.common.RequestHolder;
import nsu.edu.zsq.dao.StudentMapper;
import nsu.edu.zsq.exception.ParamException;
import nsu.edu.zsq.param.PageQuery;
import nsu.edu.zsq.service.sys.StudentService;
import nsu.edu.zsq.service.sys.SysLogService;
import nsu.edu.zsq.util.BeanValidator;
import nsu.edu.zsq.util.ExcelUtil;
import nsu.edu.zsq.util.PasswordUtil;

/** 
* Description: 学生的service实现类<br>
*/
@Slf4j
@Service
public class StudentServiceImpl implements StudentService {
    
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private SysLogService sysLogService;

    @Override
    public Student getStudent(int stuId) {
        Student student = studentMapper.selectByPrimaryKey(stuId);
        return student;
    }

    @Override
    public PageInfo<Student> listSchMajorWithPage(String majorNo, PageQuery pageQuery) {
        // 所有的学生
        String allStudent = "0";
        PageHelper.startPage(pageQuery.getPageNum(),pageQuery.getPageSize());
        StudentExample example = new StudentExample();
        Criteria createCriteria = example.createCriteria();
        // 获取所有没有删除的学生
        createCriteria.andIsDeleteEqualTo(0);
        // 根据排序号，降序
        example.setOrderByClause("sort desc");
        List<Student> listStudent = null;
        if (allStudent.equals(majorNo)) {
            listStudent = studentMapper.selectByExample(example);
        } else {
            createCriteria.andMajorNoEqualTo(majorNo);
            listStudent = studentMapper.selectByExample(example);
        }
        PageInfo<Student> pageInfo = new PageInfo<Student>(listStudent, pageQuery.getNavigatePages());
        return pageInfo;
    }
    
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveBatchStudent(List<Student> students) {
        List<Map<String, String>> after = new ArrayList<Map<String, String>>();
        for (Student student : students) {
            BeanValidator.check(student);
            if (checkStuNoExist(student.getStuNo())) {
                throw new ParamException("存在相同的学号");
            }
            Map<String, String> map = new HashMap<String, String>(2);
            map.put("stuNo", student.getStuNo());
            map.put("stuName", student.getStuName());
            after.add(map);
            // 默认密码为身份证后六位
            String password = student.getIdNumber().substring(student.getIdNumber().length() - 6);
            if (password.endsWith("X") || password.endsWith("x")) {
                password = password.replace('x', '0');
                password = password.replace('X', '0');
            }
            student.setPassword(PasswordUtil.md5(password));
			/*
			 * student.setOperator(RequestHolder.getCurrentSysUser().getAccount());
			 * student.setOperatorTime(new Date());
			 */
            studentMapper.insertSelective(student);
        }

		/*
		 * // 添加日志 String instruction = "学生信息管理-批量导入";
		 * sysLogService.saveSysLogBySysUser(null, after, instruction);
		 */
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveStudent(Student student) {
        // 数据校验
        BeanValidator.check(student);
        if (checkStuNoExist(student.getStuNo())) {
            throw new ParamException("该学号已经存在");
        }
        // 默认密码为身份证后六位
        String password = student.getIdNumber().substring(student.getIdNumber().length() - 6);
        if (password.endsWith("X") || password.endsWith("x")) {
            password = password.replace('x', '0');
            password = password.replace('X', '0');
        }
        student.setPassword(PasswordUtil.md5(password));
		/*
		 * student.setOperator(RequestHolder.getCurrentSysUser().getAccount());
		 * student.setOperatorTime(new Date());
		 */
        studentMapper.insertSelective(student);
        
		/*
		 * // 添加日志 String instruction = "学生信息管理-添加学生";
		 * sysLogService.saveSysLogBySysUser(null, student, instruction);
		 */
    }
    
    /**
     * 检查是否存在相同的学号
     * @param stuNo 学号
     * @return boolean true：存在 false：不存在
     */
    private boolean checkStuNoExist(String stuNo) {
        StudentExample example = new StudentExample();
        example.createCriteria().andStuNoEqualTo(stuNo);
        return studentMapper.countByExample(example) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteBatchStudent(int[] stuIds) {
        List<Student> before = new ArrayList<Student>();
        for (int stuId : stuIds) {
            Student student = getStudent(stuId);
            before.add(student);
            // TODO 删除学生信息的同时，删除学生关联的课程
            Student deleteStudent = new Student();
            deleteStudent.setStuId(stuId);
            deleteStudent.setIsDelete(1);
            studentMapper.updateByPrimaryKeySelective(deleteStudent);
        }

		/*
		 * // 添加日志 String instruction = "学生信息管理-批量删除";
		 * sysLogService.saveSysLogBySysUser(before, null, instruction);
		 */
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteStudent(int stuId) {
        Student before = getStudent(stuId);
        // TODO 删除学生信息的同时，删除学生关联的课程
        Student deleteStudent = new Student();
        deleteStudent.setStuId(stuId);
        deleteStudent.setIsDelete(1);
        studentMapper.updateByPrimaryKeySelective(deleteStudent);
		/*
		 * // 添加日志 String instruction = "学生信息管理-单个删除";
		 * sysLogService.saveSysLogBySysUser(before, null, instruction);
		 */

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateStudent(Student student) {
        Student before = getStudent(student.getStuId());
        // 数据校验
        BeanValidator.check(student);
        if (!before.getStuNo().equals(student.getStuNo()) && checkStuNoExist(student.getStuNo())) {
            throw new ParamException("该学号已经存在");
        }
		/*
		 * student.setOperator(RequestHolder.getCurrentSysUser().getAccount());
		 * student.setOperatorTime(new Date());
		 */
        studentMapper.updateByPrimaryKeySelective(student);
		/*
		 * // 添加日志 String instruction = "学生信息管理-编辑学生";
		 * sysLogService.saveSysLogBySysUser(before, student, instruction);
		 */
    }

    
    


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void importStudentFromExcel(MultipartFile excelFile) {
        List<Student> listStudent = ExcelUtil.importExcel(excelFile, 1, 1, Student.class);
        saveBatchStudent(listStudent);
        log.info("导入学生数据一共【{}】条",listStudent.size());

    }

    @Override
    public void exportStudentToExcel(HttpServletResponse response) {
        StudentExample example = new StudentExample();
        List<Student> listStudent = studentMapper.selectByExample(example);
        // 导出操作
        ExcelUtil.exportExcel(listStudent,"学生信息","Sheet1",Student.class,"学生信息.xlsx",response);

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void resetPassword(int stuId) {
        Student beforeStudent = getStudent(stuId);
        // 默认密码为身份证后六位
        String password = beforeStudent.getIdNumber().substring(beforeStudent.getIdNumber().length() - 6);
        if (password.endsWith("X") || password.endsWith("x")) {
            password = password.replace('x', '0');
            password = password.replace('X', '0');
        }
        Student before = Student.builder().stuId(beforeStudent.getStuId()).stuNo(beforeStudent.getStuNo())
                .password(beforeStudent.getPassword()).operator(beforeStudent.getOperator())
                .operatorTime(beforeStudent.getOperatorTime()).build();
        Student after = Student.builder().stuId(beforeStudent.getStuId()).stuNo(beforeStudent.getStuNo())
                .password(PasswordUtil.md5(password)).operator(RequestHolder.getCurrentSysUser().getAccount())
                .operatorTime(new Date()).build();
        studentMapper.updateByPrimaryKeySelective(after);
		/*
		 * // 添加日志 String instruction = "学生信息管理-重置密码";
		 * sysLogService.saveSysLogBySysUser(before, after, instruction);
		 */
    }
}
